/*
 * Copyright (C) 2016 Facishare Technology Co., Ltd. All Rights Reserved.
 */
package com.wlh.animation.ipctest;

import java.util.concurrent.CountDownLatch;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

/**
 * @author weilh
 *         <b>DATE</b> 2016/8/25.
 */
public class BinderPool {
    public static final int BINDER_NONE = -1;
    public static final int BINDER_BOOK = 0;
    public static final int BINDER_TOPIC = 1;

    private Context mContext;
    public IBinderPool mBinderPool;
    private CountDownLatch mCountDownLatch;
    private static BinderPool mInstance;
    public static BinderPool getInstance(Context context) {
        if (mInstance == null) {
            synchronized(BinderPool.class) {
                if (mInstance == null) {
                    mInstance = new BinderPool(context);
                }
            }
        }
        return mInstance;
    }

    private BinderPool(Context context) {
        mContext = context.getApplicationContext();
        connectService();
    }

    public synchronized void connectService() {
        mCountDownLatch = new CountDownLatch(1);
        mContext.bindService(new Intent(mContext, BinderPoolService.class), mBinderPoolConnection, Context
                .BIND_AUTO_CREATE);
        try {
            mCountDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public IBinder queryBinder(int binderCode) {
        if (mBinderPool == null) return null;
        try {
            return mBinderPool.queryBinder(binderCode);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }
    private ServiceConnection mBinderPoolConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinderPool = IBinderPool.Stub.asInterface(service);
            try {
                mBinderPool.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            mCountDownLatch.countDown();


        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            mBinderPool.asBinder().unlinkToDeath(mDeathRecipient, 0);
            mBinderPool = null;
            connectService();
        }
    };

    public static class IBinderPoolImpl extends IBinderPool.Stub {

        @Override
        public IBinder queryBinder(int binderCode) throws RemoteException {
            IBinder binder = null;
            switch (binderCode) {
                case BINDER_BOOK:
                    binder = new BinderPoolService.BookManagerImpl();
                    break;
                case BINDER_TOPIC:
                    binder = new BinderPoolService.TopicManagerImpl();
                    break;
            }
            return binder;
        }
    }
}
